package com.deram.ctin.serv.search.solr.service.impl;

import com.deram.ctin.common.bean.PageResult;
import com.deram.ctin.serv.search.entity.solr.bean.SolrCustomsInfo;
import com.deram.ctin.serv.search.entity.solr.bean.SolrEnterInfo;
import com.deram.ctin.serv.search.entity.solr.search.WebCustomsSearchParam;
import com.deram.ctin.serv.search.entity.solr.search.WebEnterSearchParam;
import com.deram.ctin.serv.search.solr.reporsitory.SolrEnterInfoDao;
import com.deram.ctin.serv.search.solr.service.SolrEnterInfoService;
import com.google.common.collect.Lists;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.SolrResultPage;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class SolrEnterInfoServiceImpl implements SolrEnterInfoService {


    @Autowired
    private SolrEnterInfoDao solrEnterInfoDao;

    @Autowired
    private SolrTemplate solrTemplate;
    @Override
    public SolrEnterInfo save(SolrEnterInfo solrCustomsInfo) {
        return solrEnterInfoDao.save(solrCustomsInfo);
    }

    @Override
    public void saveList(List<SolrEnterInfo> list) {
        for (SolrEnterInfo enterInfo: list) {
            solrEnterInfoDao.save(enterInfo);
        }
    }

    @Override
    public SolrEnterInfo findById(Long id) {
        return solrEnterInfoDao.findOne(id);
    }

    @Override
    public void delete(Long id) {
        solrEnterInfoDao.delete(id);
    }

    @Override
    public  List<SolrEnterInfo> findAll() {
        return Lists.newArrayList(solrEnterInfoDao.findAll()) ;
    }

    @Override
    public PageResult<SolrEnterInfo> searchByKeywords(WebEnterSearchParam keywords,Integer pageNo,Integer pageSize)  {
        Criteria criteria = createSearchConditions(keywords);
        System.out.println( criteria.toString());
        Pageable pageable = new PageRequest(pageNo-1,pageSize);
        SimpleQuery search = new SimpleQuery(criteria);
        search.setPageRequest(pageable);

        org.springframework.data.solr.core.query.Field fromField = new SimpleField("enter_id");
        org.springframework.data.solr.core.query.Field toField = new SimpleField("enterId");
        Join join = new Join(fromField,toField);
//        search.setJoin(join);
        System.out.println(search.toString());
        Page reslut = solrTemplate.queryForPage( search,SolrEnterInfo.class);
        List<SolrEnterInfo> solrEnterInfoList = reslut.getContent();
        for (int i = 0; i < solrEnterInfoList.size(); i++) {
            if(solrEnterInfoList.get(i).getEnterId()!=null){
                solrEnterInfoList.get(i).setHasCustoms(true);
                solrEnterInfoList.get(i).setHasBusiness(true);
            }else{
                solrEnterInfoList.get(i).setHasCustoms(false);
                solrEnterInfoList.get(i).setHasBusiness(true);
            }
        }
        PageResult<SolrEnterInfo> pageResult = new PageResult<>();
        pageResult.setTotal((int) reslut.getTotalElements());
        pageResult.setList(reslut.getContent());
        pageResult.setPageNo(reslut.getNumber()+1);
        pageResult.setPageSize(pageSize);
        return  pageResult;
    }

    private Criteria createSearchConditions(WebEnterSearchParam words) {
        Criteria conditions = null;
        Date beginDate = new Date();
        Date endDate = new Date();
        Calendar beginCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        if(words.getCreationDate()!=null) {
            switch (words.getCreationDate()) {
                case 1:
                    beginCalendar.setTime(beginDate);
                    beginCalendar.set(Calendar.YEAR,-1);
                    beginDate = beginCalendar.getTime();
                    endDate = new Date();
                    break;
                case 2:
                        beginCalendar.setTime(beginDate);
                        beginCalendar.set(Calendar.YEAR,-5);
                        beginDate = beginCalendar.getTime();
                        endCalendar.setTime(beginDate);
                        endCalendar.set(Calendar.YEAR,-1);
                        endDate = endCalendar.getTime();
                    break;
                case 3:
                    beginCalendar.setTime(beginDate);
                    beginCalendar.set(Calendar.YEAR,-10);
                    beginDate = beginCalendar.getTime();
                    endCalendar.setTime(beginDate);
                    endCalendar.set(Calendar.YEAR,-5);
                    endDate = endCalendar.getTime();
                    break;

                case 4:
                    beginCalendar.setTime(beginDate);
                    beginCalendar.set(Calendar.YEAR,-15);
                    beginDate = beginCalendar.getTime();
                    endCalendar.setTime(beginDate);
                    endCalendar.set(Calendar.YEAR,-10);
                    endDate = endCalendar.getTime();
                    break;
                case 5:
                    beginCalendar.setTime(beginDate);
                    beginCalendar.set(Calendar.YEAR,-50);
                    beginDate = beginCalendar.getTime();
                    endCalendar.setTime(beginDate);
                    endCalendar.set(Calendar.YEAR,-15);
                    endDate = endCalendar.getTime();
                    break;
            }
        }
        if (conditions == null) {
            conditions = new Criteria("enterKeywords").contains(words.getKeywords().split(" "))
                    .and(new Criteria("registeredCapital").between(words.getRegisteredCapitalLower(),words.getRegisteredCapitalUpper()))
                    .and(new Criteria("areaName").contains(words.getProvince()))
                    .and(new Criteria("areaName").contains(words.getCity()))
                    .and(new Criteria("industryInvolved").contains(words.getIndustryInvolved()))
                    .and(new Criteria("managementStatusName").contains(words.getManagementStatus()));

            if(words.getCreationDate()!=null){
                conditions.and(new Criteria("creationDate").between(beginDate,endDate));
            }
            if(words.getType()!=null){
                conditions.and(new Criteria("type").in(words.getType()));
            }
            if(words.getHasCustoms()){
                conditions .and(new Criteria("dollarPrice").between(words.getDollarPricePriceLower(),words.getDollarPricePriceUpper()))
                        .and(new Criteria("exportDate").between(words.getStartDate(),words.getEndDate()))
                        .and(new Criteria("dollarAmount").between(words.getDollarAmountLower(),words.getDollarAmountUpper()))
                        .and(new Criteria("legalWeight").between(words.getDollarAmountLower(),words.getDollarAmountUpper()))
                        .and(new Criteria("hsCode").contains(words.getHsCode()))
                        .and(new Criteria("hsName")).contains(words.getHsName())
                        .and(new Criteria("hsModels").contains(words.getHsModels()))
                        .and(new Criteria("tradeName").contains(words.getTradeModel()))
                        .and(new Criteria("exportCustoms").contains(words.getExportCustoms()))
                        .and(new Criteria("applicationUnit").contains(words.getApplicationUnit()))
                        .and(new Criteria("ownerUnit").contains(words.getOwnerUnit()))
                        .and(new Criteria("businessUnit").contains(words.getBusinessUnit()));
            }
        }
        else {
            conditions = new Criteria("enterKeywords").contains(words.getKeywords())
                    .and(new Criteria("registeredCapital").between(words.getRegisteredCapitalLower(),words.getRegisteredCapitalUpper()))
                            .and(new Criteria("areaName").contains(words.getProvince()))
                                    .and(new Criteria("industryInvolved").contains(words.getIndustryInvolved()));
            if(words.getManagementStatus() != null){
                 conditions.and(new Criteria("managementStatus").is(words.getManagementStatus()));
            }
            if(!words.getCreationDate().equals("")){
                conditions.and(new Criteria("creationDate").between(beginDate,endDate));
            }
        }
        return conditions;
    }

}